package models

import (
	"database/sql"
	"fmt"
	"github.com/jinzhu/gorm"
	"strconv"
	"test/system"
	// _ "github.com/mattn/go-sqlite3"
	_ "github.com/go-sql-driver/mysql"
)

//gorm-v1文档 https://v1.gorm.io/zh_CN/docs/
func ListPublishedPost(tag string, pageIndex, pageSize int) ([]*Post, error) {

	//return "models-test"+tag
	return _listPost(tag, pageIndex, pageSize)
}

func GetPostById(id string) (*Post, error) {
	pid, err := strconv.ParseUint(id, 10, 64)
	var post Post
	err = DB.First(&post, "id=?", pid).Error
	return &post, err
}

func (post *Post) UpdateView() error {
	return DB.Model(post).Updates(map[string]interface{}{
		"view": post.View,
	}).Error
}

func CreatePost() *gorm.DB {

	return DB.Create(&Post{
		Title:       "wbz4",
		Body:        "xxx",
		IsPublished: true,
	})
}

func _listPost(tag string, pageIndex, pageSize int) ([]*Post, error) {
	var posts []*Post
	var err error
	var rows *sql.Rows
	//rows, err = DB.Faw().Rows()

	if pageIndex > 0 {
		rows, err = DB.Raw("select * from posts limit ? offset ?", pageSize, pageSize*(pageIndex-1)).Rows()
	} else {
		rows, err = DB.Raw("select * from posts limit ? ").Rows()
	}

	if err != nil {
		return nil, err
	}
	defer rows.Close()
	for rows.Next() {
		var post Post
		DB.ScanRows(rows, &post)
		posts = append(posts, &post)
	}

	return posts, err
}

func CountPostByTag(tag string) (count int, err error) {
	var (
		tagId uint64
	)
	if len(tag) > 0 {
		tagId, err = strconv.ParseUint(tag, 10, 64)
		if err != nil {
			return
		}
		err = DB.Raw("select count(*) from posts p inner join post_tags pt on p.id = pt.post_id where pt.tag_id = ? and p.is_published = ?", tagId, true).Row().Scan(&count)
	} else {
		err = DB.Raw("select count(*) from posts p where p.is_published = ?", true).Row().Scan(&count)
	}
	return
}

type BaseModel struct {
	Id        uint `gorm:"primary_key"`
	CreatedAt string
	//UpdatedAt time.Time
}

type User struct {
	BaseModel
	Name string `gorm:"not_null"`
}

type Post struct {
	BaseModel
	Title       string // title
	Body        string // body
	View        int    // view count
	IsPublished bool   // published or not
	Tags        []*Tag `gorm:"-"` // tags of post
	//Comments     []*Comment `gorm:"-"` // comments of post
	CommentTotal int `gorm:"-"` // count of comment
}

type Tag struct {
	Name  string
	Total int
}

var DB *gorm.DB

func InitDB() (*gorm.DB, error) {

	// db, err := gorm.Open("sqlite3", "./test1.db3")
	// db, err := gorm.Open("mysql", "root:123456@/test?charset=utf8&parseTime=True&loc=Asia/Shanghai")
	//db, err := gorm.Open("mysql", "root:123456@/go_test?charset=utf8")
	db, err := gorm.Open("mysql", system.GetConfiguration().MYSQL)

	checkErr(err)
	fmt.Println("init DB success!!!")

	//db.Exec(sql_table)//执行数据表
	if err == nil {
		DB = db
		//db.LogMode(true)
		//db.AutoMigrate(&Page{}, &Post{}, &Tag{}, &PostTag{}, &User{}, &Comment{}, &Subscriber{}, &Link{}, &SmmsFile{})
		//db.Model(&PostTag{}).AddUniqueIndex("uk_post_tag", "post_id", "tag_id")
		return db, err
	}
	return nil, err
}

func checkErr(err error) {
	if err != nil {
		panic(err)
	}
}
